﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Resources;

namespace ProgNetExtensions.LanguageExt
{
    public class Language
    {
        private static Dictionary<string, Language> languages;
        private static Language current;

        /// <summary>
        /// Gets or sets current language
        /// </summary>
        public static Language Current
        {
            get { return current; }
            set
            {
                current = value;
                if (LanguageChanged != null)
                {
                    LanguageChanged(null, EventArgs.Empty);
                }
            }
        }
        /// <summary>
        /// Gets language with specified code
        /// </summary>
        /// <param name="code"></param>
        /// <returns></returns>
        public static Language GetLanguage(string code)
        {
            if (Languages.ContainsKey(code))
                return Languages[code];
            return null;
        }
        
        private static Dictionary<string, Language> Languages
        {
            get
            {
                if (languages == null)
                    languages = new Dictionary<string, Language>();
                return languages;
            }
        }

       
        private string code, name;
        private Dictionary<string, ResourceManager> managers;

        /// <summary>
        /// Language code
        /// </summary>
        public string Code
        {
            get { return code; }
        }
        /// <summary>
        /// Language name
        /// </summary>
        public string Name
        {
            get { return name; }
        }

        public Language(string code, string name)
        {
            if (!Languages.ContainsKey(code))
            {
                this.code = code;
                this.name = name;
                Languages.Add(code, this);
                if (Current == null)
                    current = this;
            }
            else
            {
                throw new Exception("Duplicate language with code " + code);
            }
        }
        /// <summary>
        /// String to be returned if GetLngString() method will not find specified entry in ResourceManager(s)
        /// </summary>
        public static string NO_ENTRY
        {
            get;
            set;
        }
        
        /// <summary>
        /// Event ocures when language has been changed
        /// </summary>
        public static event EventHandler LanguageChanged;

        public void AddManager(string mgrCode, Type resMgrType)
        {
            Managers.Add(mgrCode, new ResourceManager(resMgrType));
        }

        private Dictionary<string, ResourceManager> Managers
        {
            get
            {
                if (managers == null)
                {
                    managers = new Dictionary<string, ResourceManager>();
                }
                return managers;
            }
        }

        public string GetLngString(string mgr, string code, params string[] parameters)
        {
            string result = null;
            if (mgr.IsNotEmpty())
            {
                if (Managers.ContainsKey(mgr))
                {
                    ResourceManager m = Managers[mgr];
                    result = m.GetString(code);
                }
            }
            else
            {
                foreach (ResourceManager m in Managers.Values)
                {
                    result = m.GetString(code);
                    if (result.IsNotEmpty())
                    {
                        break;
                    }
                }
            }
            if (result.IsNotEmpty())
            {
                if (parameters != null)
                {
                    result = string.Format(result, parameters);
                }
            }
            else
            {
                result = (NO_ENTRY.IsEmpty() ? "No Data" : NO_ENTRY);
            }
            return result;
        }

        public string GetLngString(string code, params string[] parameters)
        {
            return GetLngString(null, code, parameters);
        }
    }
}
